package com.zxx.ssm.util;

import org.apache.commons.lang.ArrayUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zxx on 2016/12/3.
 */
public class StringUtils {

    /**
     * 默认字符串-->整型转换异常错误码
     */
    public static final int NUMBER_CAST_ERR = -100;
    /**
     * The empty String <code>""</code>.
     *
     * @since 2.0
     */
    public static final String EMPTY = "";

    /**
     * Represents a failed index search.
     *
     * @since 2.1
     */
    public static final int INDEX_NOT_FOUND = -1;
    /**
     * long 型参数默认值
     */
    private static final long defaultLong = 0L;

    /**
     * 执行trim操作（包含全角和半角的空格;）
     *
     * @param str 字符串
     * @return 结果字符串
     */
    public static String trim(String str) {
        if (isBlank(str)) {
            return "";
        } else {
            str = str.trim();// 去掉半角符号的空格
            while (str.startsWith("　")) {//该空格为全角空格
                str = str.substring(1, str.length()).trim();
                if (isBlank(str)) {
                    return "";
                }
            }
            while (str.endsWith("　")) { // 该空格为全角空格
                str = str.substring(0, str.length() - 1).trim();
                if (isBlank(str)) {
                    return "";
                }
            }
        }
        return str;
    }

    /**
     * 使用指定字符替换空格（包含全角和半角的空格）
     *
     * @param str  字符串
     * @param with 指定字符串
     * @return 结果字符串
     */
    public static String replaceSpace(String str, String with) {
        if (isBlank(str)) {
            return str;
        }
        // 转换全角的字符串
        String text = str.replace("　", with);

        // 转换半角的字符串
        return text.replace(" ", with);
    }

    /**
     * 将字符串<code>String</code>转化为<code>Long</code>
     *
     * @param str 将要转化的字符串，可以为任意字符串
     * @return long 转化失败自动返回默认值
     */
    public static long parse2Long(String str) {
        return parse2Long(str, defaultLong);
    }

    /**
     * 将字符串<code>String</code>转化为<code>Long</code>
     * <pre>
     * StringUtils.parse2Long(null, 123) == 123;
     * StringUtils.parse2Long("12d2", 123) == 123;
     * StringUtils.parse2Long("12 12", 123) == 123;
     * StringUtils.parse2Long("1234", 123) == 1234;
     * StringUtils.parse2Long(" 1234 ", 123) == 1234;
     * <pre>
     *
     * @param str         将要转化的字符串，可以是任意字符串
     * @param defaultLong 转化异常时被赋予的默认值
     * @return long 转化结果
     */
    public static long parse2Long(String str, long defaultLong) {
        try {
            long l = Long.valueOf(trim(str));
            return l;
        } catch (NumberFormatException e) {
            return defaultLong;
        }
    }

    /**
     * *将字符串<code>String</code>转化为<code>String</code>
     * <pre>
     * <pre>
     *
     * @param format
     * @param str
     * @return
     */
    public static String parse2SpecficNumString(String format, Integer str) {
        try {
            String s = String.format(format, str);
            return s;
        } catch (Exception e) {
            return String.valueOf(str);
        }
    }

    /**
     * 将字符串转换为int。如果转换抛出异常，则将结果设为默认值-100
     * <p>
     * <pre>
     *      StringUtils.toInt(null) = -100;<br>
     *      StringUtils.toInt("")   = -100;<br>
     *      StringUtils.toInt("aa") = -100;<br>
     *      StringUtils.toInt("12") = 12;
     * </pre>
     *
     * @param str a String containing the int representation to be parsed
     * @return int the integer value represented by the argument in decimal
     */
    public static int toInt(String str) {
        try {
            return Integer.parseInt(str);
        } catch (NumberFormatException e) {
            return NUMBER_CAST_ERR;
        }
    }

    /**
     * 向整型数组中加入一个整型的值
     * <p>
     * <p>
     * StringUtils.addInt({1,2,3},4) = {1,2,3,4}
     * </p>
     *
     * @param arg0 目标数组
     * @param arg1 要加入的值
     * @return int[]
     */
    public static int[] addInt(int[] arg0, int arg1) {
        if (arg1 == NUMBER_CAST_ERR) {
            return arg0;
        }
        int[] arg2 = new int[arg0.length + 1];
        System.arraycopy(arg0, 0, arg2, 0, arg0.length);
        arg2[arg0.length] = arg1;
        return arg2;
    }

    /**
     * 全角转半角：
     *
     * @param str
     * @return
     */
    public static String qbTransfer(String str) {
        if (str == null) {
            return "";
        }

        char[] c = str.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] == 12288) {
                c[i] = (char) 32;
                continue;
            }
            if (c[i] > 65280 && c[i] < 65375) {
                c[i] = (char) (c[i] - 65248);
            }
        }
        return new String(c);
    }

    /**
     * 半角转全角：
     *
     * @param str
     * @return
     */
    public static String bqTransfer(String str) {

        if (str == null) {
            return "";
        }
        char[] c = str.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] == 32) {
                c[i] = (char) 12288;
                continue;
            }
            if (c[i] < 127) {
                c[i] = (char) (c[i] + 65248);
            }
        }
        return new String(c);
    }

    /**
     * 将String[]转换为Long[]
     *
     * @param str
     * @return
     */
    public static long[] paseToLongArray(String[] str) {
        long[] result = new long[str.length];
        for (int i = 0; i < str.length; i++) {
            result[i] = parse2Long(str[i]);
        }
        return result;
    }

    /***
     * 计算字符串的存储长度，通过字节Byte计算
     *
     * @param str
     * @return
     */
    public static int storeLength(String str) {
        if (str != null) {
            return str.getBytes().length;
        }
        return 0;
    }

    /**
     * 判断字符串是否包含在数组中
     *
     * @param args
     * @param value
     * @return true:包含   false:不包含
     */
    public static boolean isInclude(String[] args, String value) {
        if (ArrayUtils.isEmpty(args) || isEmpty(value)) {
            return false;
        }
        return ArrayUtils.contains(args, value);
    }

    /**
     * 在字符串中查找指定字符串，并返回第一个匹配的索引值。如果字符串为<code>null</code>或未找到，则返回<code>-1</code>。
     * <pre>
     * StringUtil.indexOf(null, *)          = -1
     * StringUtil.indexOf(*, null)          = -1
     * StringUtil.indexOf("", "")           = 0
     * StringUtil.indexOf("aabaabaa", "a")  = 0
     * StringUtil.indexOf("aabaabaa", "b")  = 2
     * StringUtil.indexOf("aabaabaa", "ab") = 1
     * StringUtil.indexOf("aabaabaa", "")   = 0
     * </pre>
     *
     * @param str       要扫描的字符串
     * @param searchStr 要查找的字符串
     * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到，则返回<code>-1</code>
     */
    public static int indexOf(String str, String searchStr) {
        if ((str == null) || (searchStr == null)) {
            return -1;
        }

        return str.indexOf(searchStr);
    }

    /**
     * 比较两个字符串（大小写敏感）。
     * <pre>
     * StringUtil.equals(null, null)   = true
     * StringUtil.equals(null, "abc")  = false
     * StringUtil.equals("abc", null)  = false
     * StringUtil.equals("abc", "abc") = true
     * StringUtil.equals("abc", "ABC") = false
     * </pre>
     *
     * @param str1 要比较的字符串1
     * @param str2 要比较的字符串2
     * @return 如果两个字符串相同，或者都是<code>null</code>，则返回<code>true</code>
     */
    public static boolean equals(String str1, String str2) {
        if (str1 == null) {
            return str2 == null;
        }

        return str1.equals(str2);
    }

    /**
     * 获取可链接的URL
     *
     * @param url
     * @return
     */
    public static String getLinkableUrl(String url) {
        if (StringUtils.isEmpty(url)) {
            return url;
        }

        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            url = "http://" + url;
        }

        return url;
    }


    /**
     * 对列表里的字符串去空格
     *
     * @param list
     * @return
     */
    public static List<String> trimList(List<String> list) {
        if (list == null) {
            return null;
        }
        List<String> r = new ArrayList<String>();
        for (String s : list) {
            r.add(trim(s));
        }
        return r;
    }

    /**
     * 把Integer类型转成String类型
     *
     * @param intValue Integer类型
     * @return String类型
     */
    public static String num2String(Integer intValue) {
        if (intValue == null) {
            return EMPTY;
        }
        return String.valueOf(intValue);
    }

    /**
     * 字符串不相同判断（大小写敏感）
     *
     * @param str1
     * @param str2
     * @return true：不相同，false：相同
     */
    public static boolean notEquals(String str1, String str2) {

        return !equals(str1, str2);

    }

    /**
     * <p>Checks if a String is empty ("") or null.</p>
     * <p>
     * <pre>
     * StringUtils.isEmpty(null)      = true
     * StringUtils.isEmpty("")        = true
     * StringUtils.isEmpty(" ")       = false
     * StringUtils.isEmpty("bob")     = false
     * StringUtils.isEmpty("  bob  ") = false
     * </pre>
     * <p>
     * <p>NOTE: This method changed in Lang version 2.0.
     * It no longer trims the String.
     * That functionality is available in isBlank().</p>
     *
     * @param str the String to check, may be null
     * @return <code>true</code> if the String is empty or null
     */
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }

    /**
     * <p>Gets the substring after the last occurrence of a separator.
     * The separator is not returned.</p>
     * <p>
     * <p>A <code>null</code> string input will return <code>null</code>.
     * An empty ("") string input will return the empty string.
     * An empty or <code>null</code> separator will return the empty string if
     * the input string is not <code>null</code>.</p>
     * <p>
     * <p>If nothing is found, the empty string is returned.</p>
     * <p>
     * <pre>
     * StringUtils.substringAfterLast(null, *)      = null
     * StringUtils.substringAfterLast("", *)        = ""
     * StringUtils.substringAfterLast(*, "")        = ""
     * StringUtils.substringAfterLast(*, null)      = ""
     * StringUtils.substringAfterLast("abc", "a")   = "bc"
     * StringUtils.substringAfterLast("abcba", "b") = "a"
     * StringUtils.substringAfterLast("abc", "c")   = ""
     * StringUtils.substringAfterLast("a", "a")     = ""
     * StringUtils.substringAfterLast("a", "z")     = ""
     * </pre>
     *
     * @param str       the String to get a substring from, may be null
     * @param separator the String to search for, may be null
     * @return the substring after the last occurrence of the separator,
     * <code>null</code> if null String input
     * @since 2.0
     */
    public static String substringAfterLast(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        }
        if (isEmpty(separator)) {
            return EMPTY;
        }
        int pos = str.lastIndexOf(separator);
        if (pos == INDEX_NOT_FOUND || pos == (str.length() - separator.length())) {
            return EMPTY;
        }
        return str.substring(pos + separator.length());
    }

    /**
     * <p>Checks if a String is whitespace, empty ("") or null.</p>
     * <p>
     * <pre>
     * StringUtils.isBlank(null)      = true
     * StringUtils.isBlank("")        = true
     * StringUtils.isBlank(" ")       = true
     * StringUtils.isBlank("bob")     = false
     * StringUtils.isBlank("  bob  ") = false
     * </pre>
     *
     * @param str the String to check, may be null
     * @return <code>true</code> if the String is null, empty or whitespace
     * @since 2.0
     */
    public static boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>Checks if a String is not empty (""), not null and not whitespace only.</p>
     * <p>
     * <pre>
     * StringUtils.isNotBlank(null)      = false
     * StringUtils.isNotBlank("")        = false
     * StringUtils.isNotBlank(" ")       = false
     * StringUtils.isNotBlank("bob")     = true
     * StringUtils.isNotBlank("  bob  ") = true
     * </pre>
     *
     * @param str the String to check, may be null
     * @return <code>true</code> if the String is
     * not empty and not null and not whitespace
     * @since 2.0
     */
    public static boolean isNotBlank(String str) {
        return !StringUtils.isBlank(str);
    }

    /**
     * <p>Compares two Strings, returning <code>true</code> if they are equal ignoring
     * the case.</p>
     * <p>
     * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
     * references are considered equal. Comparison is case insensitive.</p>
     * <p>
     * <pre>
     * StringUtils.equalsIgnoreCase(null, null)   = true
     * StringUtils.equalsIgnoreCase(null, "abc")  = false
     * StringUtils.equalsIgnoreCase("abc", null)  = false
     * StringUtils.equalsIgnoreCase("abc", "abc") = true
     * StringUtils.equalsIgnoreCase("abc", "ABC") = true
     * </pre>
     *
     * @param str1 the first String, may be null
     * @param str2 the second String, may be null
     * @return <code>true</code> if the Strings are equal, case insensitive, or
     * both <code>null</code>
     * @see java.lang.String#equalsIgnoreCase(String)
     */
    public static boolean equalsIgnoreCase(String str1, String str2) {
        return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2);
    }

    /**
     * <p>Gets the substring before the first occurrence of a separator.
     * The separator is not returned.</p>
     * <p>
     * <p>A <code>null</code> string input will return <code>null</code>.
     * An empty ("") string input will return the empty string.
     * A <code>null</code> separator will return the input string.</p>
     * <p>
     * <p>If nothing is found, the string input is returned.</p>
     * <p>
     * <pre>
     * StringUtils.substringBefore(null, *)      = null
     * StringUtils.substringBefore("", *)        = ""
     * StringUtils.substringBefore("abc", "a")   = ""
     * StringUtils.substringBefore("abcba", "b") = "a"
     * StringUtils.substringBefore("abc", "c")   = "ab"
     * StringUtils.substringBefore("abc", "d")   = "abc"
     * StringUtils.substringBefore("abc", "")    = ""
     * StringUtils.substringBefore("abc", null)  = "abc"
     * </pre>
     *
     * @param str       the String to get a substring from, may be null
     * @param separator the String to search for, may be null
     * @return the substring before the first occurrence of the separator,
     * <code>null</code> if null String input
     * @since 2.0
     */
    public static String substringBefore(String str, String separator) {
        if (isEmpty(str) || separator == null) {
            return str;
        }
        if (separator.length() == 0) {
            return EMPTY;
        }
        int pos = str.indexOf(separator);
        if (pos == INDEX_NOT_FOUND) {
            return str;
        }
        return str.substring(0, pos);
    }

    /**
     * <p>Case insensitive check if a String starts with a specified prefix.</p>
     * <p>
     * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
     * references are considered to be equal. The comparison is case insensitive.</p>
     * <p>
     * <pre>
     * StringUtils.startsWithIgnoreCase(null, null)      = true
     * StringUtils.startsWithIgnoreCase(null, "abc")     = false
     * StringUtils.startsWithIgnoreCase("abcdef", null)  = false
     * StringUtils.startsWithIgnoreCase("abcdef", "abc") = true
     * StringUtils.startsWithIgnoreCase("ABCDEF", "abc") = true
     * </pre>
     *
     * @param str    the String to check, may be null
     * @param prefix the prefix to find, may be null
     * @return <code>true</code> if the String starts with the prefix, case insensitive, or
     * both <code>null</code>
     * @see java.lang.String#startsWith(String)
     * @since 2.4
     */
    public static boolean startsWithIgnoreCase(String str, String prefix) {
        return startsWith(str, prefix, true);
    }

    /**
     * <p>Check if a String starts with a specified prefix (optionally case insensitive).</p>
     *
     * @param str        the String to check, may be null
     * @param prefix     the prefix to find, may be null
     * @param ignoreCase inidicates whether the compare should ignore case
     *                   (case insensitive) or not.
     * @return <code>true</code> if the String starts with the prefix or
     * both <code>null</code>
     * @see java.lang.String#startsWith(String)
     */
    private static boolean startsWith(String str, String prefix, boolean ignoreCase) {
        if (str == null || prefix == null) {
            return (str == null && prefix == null);
        }
        if (prefix.length() > str.length()) {
            return false;
        }
        return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
    }

    /**
     * <p>Gets the substring after the first occurrence of a separator.
     * The separator is not returned.</p>
     * <p>
     * <p>A <code>null</code> string input will return <code>null</code>.
     * An empty ("") string input will return the empty string.
     * A <code>null</code> separator will return the empty string if the
     * input string is not <code>null</code>.</p>
     * <p>
     * <p>If nothing is found, the empty string is returned.</p>
     * <p>
     * <pre>
     * StringUtils.substringAfter(null, *)      = null
     * StringUtils.substringAfter("", *)        = ""
     * StringUtils.substringAfter(*, null)      = ""
     * StringUtils.substringAfter("abc", "a")   = "bc"
     * StringUtils.substringAfter("abcba", "b") = "cba"
     * StringUtils.substringAfter("abc", "c")   = ""
     * StringUtils.substringAfter("abc", "d")   = ""
     * StringUtils.substringAfter("abc", "")    = "abc"
     * </pre>
     *
     * @param str       the String to get a substring from, may be null
     * @param separator the String to search for, may be null
     * @return the substring after the first occurrence of the separator,
     * <code>null</code> if null String input
     * @since 2.0
     */
    public static String substringAfter(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        }
        if (separator == null) {
            return EMPTY;
        }
        int pos = str.indexOf(separator);
        if (pos == INDEX_NOT_FOUND) {
            return EMPTY;
        }
        return str.substring(pos + separator.length());
    }

    /**
     * <p>Check if a String starts with a specified prefix.</p>
     * <p>
     * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
     * references are considered to be equal. The comparison is case sensitive.</p>
     * <p>
     * <pre>
     * StringUtils.startsWith(null, null)      = true
     * StringUtils.startsWith(null, "abc")     = false
     * StringUtils.startsWith("abcdef", null)  = false
     * StringUtils.startsWith("abcdef", "abc") = true
     * StringUtils.startsWith("ABCDEF", "abc") = false
     * </pre>
     *
     * @param str    the String to check, may be null
     * @param prefix the prefix to find, may be null
     * @return <code>true</code> if the String starts with the prefix, case sensitive, or
     * both <code>null</code>
     * @see java.lang.String#startsWith(String)
     * @since 2.4
     */
    public static boolean startsWith(String str, String prefix) {
        return startsWith(str, prefix, false);
    }

    public static String humpToUnderLine(String str) {

        List record = new ArrayList();
        for (int i = 0; i < str.length(); i++) {
            char tmp = str.charAt(i);

            if ((tmp <= 'Z') && (tmp >= 'A')) {
                record.add(i);//记录每个大写字母的位置
            }

        }
        record.remove(0);//第一个不需加下划线

        str = str.toLowerCase();
        char[] charofstr = str.toCharArray();
        String[] t = new String[record.size()];
        for (int i = 0; i < record.size(); i++) {
            t[i] = "_" + charofstr[(Integer) record.get(i)];//加“_”
        }
        String result = "";
        int flag = 0;
        for (int i = 0; i < str.length(); i++) {
            if ((flag < record.size()) && (i == (Integer) record.get(flag))) {
                result += t[flag];
                flag++;
            } else
                result += charofstr[i];
        }

        return result;
    }
}

